package com.wfit.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wfit.admin.common.Constants;
import com.wfit.admin.entity.Menu;
import com.wfit.admin.entity.Role;
import com.wfit.admin.entity.dto.UserDTO;
import com.wfit.admin.exception.ServiceException;
import com.wfit.admin.mapper.RoleMapper;
import com.wfit.admin.mapper.RoleMenuMapper;
import com.wfit.admin.service.impl.MenuServiceImpl;
import com.wfit.config.JwtProperties;
import com.wfit.constant.MessageConstant;
import com.wfit.context.UserContext;
import com.wfit.dto.LoginFormDTO;
import com.wfit.dto.RegisterDto;
import com.wfit.dto.UserNameEmailDTO;
import com.wfit.exception.BadRequestException;
import com.wfit.mapper.UsersMapper;
import com.wfit.po.Users;
import com.wfit.result.Result;
import com.wfit.service.UsersService;
import com.wfit.utils.JwtTool;
import com.wfit.vo.UsersInfoVO;
import com.wfit.vo.UsersLoginVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements UsersService {

    private final PasswordEncoder passwordEncoder;

    private final JwtTool jwtTool;

    private final JwtProperties jwtProperties;

    @Override
    public UsersLoginVO login(LoginFormDTO loginDTO) {
        // 1.数据校验
        String username = loginDTO.getUsername();
        String password = loginDTO.getPassword();

        // 2.根据用户名或手机号查询
        Users users = lambdaQuery().eq(Users::getUserName, username).one();

        // 3.校验是否禁用
//        if (user.getStatus() == UserStatus.FROZEN) {
//            throw new ForbiddenException("用户被冻结");
//        }
        // 4.校验密码

        if (users == null) throw new BadRequestException("用户不存在");
        Boolean b = passwordEncoder.matches(password, users.getPassword());
        if (!b  /*TOOD !passwordEncoder.matches(password, users.getPassword())*/) {
            throw new BadRequestException("用户名或密码错误");
        }

        // 5.生成TOKEN
        String token = jwtTool.createToken(users.getId(), jwtProperties.getTokenTTL());
        // 6.封装VO返回
        UsersLoginVO vo = new UsersLoginVO();
        BeanUtils.copyProperties(users, vo);
        vo.setToken(token);

        // 获取角色和菜单
        vo.setRole(users.getRole());
        List<Menu> roleMenus = getRoleMenus(users.getRole());
        vo.setMenus(roleMenus);
        return vo;
    }

    @Override
    public Result register(RegisterDto dto) {
        if (dto != null) {
            return Result.error(MessageConstant.PARAM_IS_NULL);
        }

        if (checkParam(dto)) return Result.error(MessageConstant.ERROR_PARAM);

        if (!(dto.getPassword() == dto.getRePassword())) {
            return Result.error(MessageConstant.PASSWORD_NOT_EQUAL_REPASSWORD);
        }
        Users users = new Users();
        users.setUserName(dto.getUsername());
        users.setPassword(passwordEncoder.encode(dto.getPassword()));
        return Result.success(MessageConstant.REGISTER_SUCCESS);
    }

    @Override
    public Result updateNameAndEmail(UserNameEmailDTO dto) {
        Users byId = getById(UserContext.getUser());
        byId.setNickName(dto.getNickname());
        byId.setEmail(dto.getEmail());
        updateById(byId);
        return Result.success();
    }

    @Override
    public Result getOneUser() {
        Users users = getById(UserContext.getUser());
        UsersInfoVO usersInfoVO = new UsersInfoVO();
        BeanUtils.copyProperties(users,usersInfoVO);
        List<Menu> roleMenus = getRoleMenus(users.getRole());
        usersInfoVO.setMenus(roleMenus);
        return Result.success(usersInfoVO);
    }

    // 验证参数不为空
    private boolean checkParam(RegisterDto dto) {
        if(StringUtils.isBlank(dto.getUsername()) || StringUtils.isBlank(dto.getPassword()) || StringUtils.isBlank(dto.getRePassword())) {
            return true;
        }
        return false;
    }

    @Resource
    private MenuServiceImpl menuService;
    @Resource
    private RoleMenuMapper roleMenuMapper;
    @Resource
    private RoleMapper roleMapper;
    private List<Menu> getRoleMenus(String roleFlag) {
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.eq("flag", roleFlag);
        Role role1 = roleMapper.selectOne(roleQueryWrapper);
        Integer roleId = role1.getId();
        List<Integer> menuIds = roleMenuMapper.selectByRoleId(roleId);
        // 查出系统所有的菜单(树形)
        List<Menu> menus = menuService.findMenus("");
        // new一个最后筛选完成之后的list
        List<Menu> roleMenus = new ArrayList<>();
        // 筛选当前用户角色的菜单
        for (Menu menu : menus) {
            if (menuIds.contains(menu.getId())) {
                roleMenus.add(menu);
            }
            List<Menu> children = menu.getChildren();
            // removeIf()  移除 children 里面不在 menuIds集合中的 元素
            children.removeIf(child -> !menuIds.contains(child.getId()));
        }
        return roleMenus;
    }
}
